﻿using System.Windows;
using VXCompany.SilverlightLogging.MVVM.Models;
using VXCompany.SilverlightLogging.ServiceProxy;
using VXCompany.SilverlightLogging.MVVM.Models.Stores;

namespace VXCompany.SilverlightLogging
{
	/// <summary>
	/// Provides logging as a service to the application.
	/// </summary>
	public class LoggingApplicationService : DependencyObject, System.Windows.IApplicationLifetimeAware, System.Windows.IApplicationService
	{
		/// <summary>
		/// Gets the current exceptionPolicy.
		/// </summary>
		public ExceptionPolicy ExceptionPolicy { get; private set; }

		/// <summary>
		/// Gets or sets logging Store.
		/// </summary>
		public IStore Store
		{
			get { return (IStore)GetValue(StoreProperty); }
			set { SetValue(StoreProperty, value); }
		}

		/// <summary>
		/// Dependency property for Store property.
		/// </summary>
		public static readonly DependencyProperty StoreProperty =
			DependencyProperty.Register("Store", typeof(IStore), typeof(LoggingApplicationService), new PropertyMetadata(null));


		/// <summary>
		/// Gets or sets LoggingServiceClientFactory
		/// </summary>
		public ILoggingServiceClientFactory LoggingServiceClientFactory
		{
			get { return (ILoggingServiceClientFactory)GetValue(LoggingServiceClientFactoryProperty); }
			set { SetValue(LoggingServiceClientFactoryProperty, value); }
		}

		/// <summary>
		/// DependencyProperty for LoggingServiceClientFactory property
		/// </summary>
		public static readonly DependencyProperty LoggingServiceClientFactoryProperty =
			DependencyProperty.Register("LoggingServiceClientFactory", typeof(ILoggingServiceClientFactory), typeof(LoggingApplicationService), new PropertyMetadata(null));

		/// <summary>
		/// Gets or sets Logging service.
		/// </summary>
		public string ApplicationName
		{
			get { return (string)GetValue(ApplicationNameProperty); }
			set { SetValue(ApplicationNameProperty, value); }
		}

		/// <summary>
		/// DependencyProperty for LoggingServiceClient property
		/// </summary>
		public static readonly DependencyProperty ApplicationNameProperty =
			DependencyProperty.Register("ApplicationName", typeof(string), typeof(LoggingApplicationService), new PropertyMetadata("Silverlight or WP7 client application"));

		/// <summary>
		/// Gets current instance of the service.
		/// </summary>
		public static LoggingApplicationService Current { get; private set; }

		#region IApplicationLifetimeAware Members

		/// <summary>
		/// Called by an application immediately after the System.Windows.Application.Startup event occurs. 
		/// Initializes logging service client.
		/// </summary>
		/// <param name="context"></param>
		public void Started()
		{		
			ExceptionPolicy.LoggingServiceFactory = this.LoggingServiceClientFactory;
			ExceptionPolicy.InitializeServiceClient();			
		}


		/// <summary>
		/// Called by an application immediately before the System.Windows.Application.Exit event occurs.
		/// Stops logging appservice. Sets policy to null.
		/// </summary>
		public void Exiting()
		{
			Current = null;
		}

		/// <summary>
		///  Called by an application immediately before the System.Windows.Application.Startup event occurs.
		///  Not implemented
		/// </summary>
		public void Starting()
		{ }

		/// <summary>
		/// Called by an application immediately after the System.Windows.Application.Exit event occurs.
		/// Not implemented
		/// </summary>
		public void Exited()
		{ 			
		}

		#endregion IApplicationLifetimeAware Members

		#region IApplicationService Members

		/// <summary>
		/// Start Service is called before Application_Startup.
		/// Creates ExceptionPolicy.
		/// </summary>
		/// <param name="context"></param>
		void IApplicationService.StartService(ApplicationServiceContext context)
		{
			Current = this;
			ExceptionPolicy = new ExceptionPolicy();			
			ExceptionPolicy.ApplicationName = this.ApplicationName;
			IStore store = this.Store;
			ExceptionPolicy.TryInitializeStore(ref store);
		}

		/// <summary>
		/// Not implemented. Stop Service is called before Application_Exited.
		/// </summary>
		void IApplicationService.StopService()
		{
		}

		#endregion IApplicationService Members
	}
}
